#pragma once

#include <vector>

/*
Interface definition of a class that can populate destination arrays with some sample
*/
class SampleDataProvider
{
public:
	SampleDataProvider(void){}
	~SampleDataProvider(void){}

	virtual void GetData(short* destination, unsigned int length) = 0;
	double intensity;
};

/*
SampleDataProvider that stores a sample to be uses when populating destination array in GetData
*/
class SampleDataProviderImpl : public SampleDataProvider
{
public:
	short* sample;
	SampleDataProviderImpl(short* sample, double intensity)
	{
		this->sample=sample; 
		this->intensity=intensity;
	}
	~SampleDataProviderImpl(void){}

	void GetData(short* destination, unsigned int length)
	{
		for(unsigned int i=0; i<length; i++)
		{
			destination[i] = sample[i];
		}
	}
};

/*
Utility class for making various operations on a sample.
*/
class Sample
{
public:
	Sample(void);
	Sample(unsigned int length);
	Sample(short* sample, unsigned int length);
	~Sample(void);

	/*
	Copying methods
	*/
	void CopyFrom(Sample* origin1, Sample* origin2);
	void CopyTo(Sample& destination, double multiplier);
	void CopyToDouble(std::vector<double>& destination);

	/*
	Low pass filter
	*/
	void LowPassFilter(Sample& destination, double gain, double neg, double pos);

	/*
	Filter that passes everything with frequency under 400
	*/
	void LowPass400Filter(Sample& destination);

	/*
	Filter that passes everything with frequency under 6000
	*/
	void LowPass6000Filter(Sample& destination);

	/*
	Mix current sample with white noise, max intensity=1
	*/
	void AddWhiteNoise(double intensity);

	/*
	Mix current sample with brown noise, max intensity=1
	*/
	void AddBrownNoise(double intensity);

	/*
	Set all array indices to 0, making the sample silent
	*/
	void Silence();

	/*
	Mix samples provided by the sample providers
	*/
	void Mix(std::vector<SampleDataProvider*>& providers, unsigned int length);

	/*
	Mix samples in the sample vector
	*/
	void Mix(std::vector<short*>& samples, std::vector<double>& intensities, unsigned int length);

	/*
	Return pointer to the sample array
	*/
	short* GetData();

	/*
	Return the length of the sample array
	*/
	unsigned int GetLength();

	/*
	Resize the sample array to 'length'
	*/
	void SetLength(unsigned int length);
	
private:
	std::vector<short> data;
};




